Skip to content

Add appearance-descriptor sidecar (sim half of multi-operator re-id) - #101

Merged
bamdadd merged 3 commits into
mainfrom
feat/appearance-sidecar
Aug 3, 2026
Merged

Add appearance-descriptor sidecar (sim half of multi-operator re-id)#101
bamdadd merged 3 commits into
mainfrom
feat/appearance-sidecar

Conversation

@bamdadd

@bamdadd bamdadd commented Aug 3, 2026

Copy link
Copy Markdown
Owner

A seeded, pixel-free, GT-derived appearance-descriptor sidecar so a cross-camera fuser can disambiguate subjects that geometry alone cannot (the collinear / ambiguous case). This is the sim half of multi-operator re-id; the rt SimTableDescriptor consumer follows.

What it is

src/multicam_sim/appearance.py, mirroring the additive-sidecar pattern of activity.py:

  • EntityAppearance(BaseModel, frozen): entity_id: str, descriptor: list[float] (unit-norm).
  • AppearanceTable(BaseModel, frozen): dim (default 512), separation (0..1), seed, entries, plus AppearanceTable.sample(entity_ids, dim=512, separation=..., seed=...). It draws one per-entity anchor with numpy.random.default_rng(seed) in a fixed order, unit-normalizes, blends each anchor toward the shared mean by (1 - separation), and renormalizes.

Attached to Scene as appearance: AppearanceTable | None = None.

Additive / opt-in, byte-golden safe

None by default and never read by the manifest builder, so the analytic manifest is byte-identical whether or not the sidecar is attached. Two tests prove it: the manifest bytes with and without the sidecar are exactly equal, and the manifest never contains appearance GT.

The separation knob = the re-id dose-response axis

separation monotonically controls the mean pairwise inter-entity cosine similarity: 1.0 gives near-orthogonal, perfectly separable descriptors (the easy case), 0.0 collapses every descriptor onto a shared mean (indistinguishable). Sweeping it traces how re-id accuracy degrades as identities become harder to separate. Monotonicity is verified across 3 seeds.

Pixel-free, GT-derived, does NOT leak the GT id

No pixels are rendered or read; the descriptor is a synthetic stand-in for a learned re-id embedding and models OSNet-style confusability. It does not encode and cannot be inverted to the ground-truth entity_id (a test renames entities and confirms the vectors are unchanged), so the fuser is not handed the answer.

Checks

uv run pytest -q, ruff check, ruff format --check, and mypy src all pass.

bamdadd added 3 commits August 3, 2026 13:51
A seeded, pixel-free, GT-derived appearance descriptor for cross-camera re-id:
EntityAppearance (unit-norm descriptor keyed by entity_id) and AppearanceTable
with a classmethod sample(entity_ids, dim, separation, seed). Descriptors are
drawn deterministically (numpy default_rng, fixed draw order), unit-normalized
anchors blended toward their shared mean by (1 - separation) and renormalized,
so the separation knob monotonically controls inter-entity cosine similarity
(1.0 near-orthogonal/separable, 0.0 collapsed/indistinguishable).

The descriptor does NOT encode the GT entity id; it models OSNet-style
confusability, and separation is the dose-response axis for re-id eval.
Exported from the package top level.
Scene.appearance: AppearanceTable | None = None. Same additive contract as
possession/activity: None by default and never read by the manifest builder, so
the byte-golden analytic manifest is unchanged whether or not the sidecar is
present.
Covers determinism across 3 seeds (identical descriptors for identical inputs,
distinct-but-valid unit vectors across seeds), monotonicity of the separation
knob (mean pairwise inter-entity cosine similarity strictly increases as
separation falls 1.0 -> 0.0), unit-norm and dim-shape invariants, empty and
single-entity edge cases, and that the descriptor does not encode the GT id.

Byte-golden: a scene with the sidecar attached produces a manifest byte-identical
to the same scene without it, and the manifest never contains appearance GT.
@bamdadd
bamdadd merged commit 567bb0a into main Aug 3, 2026
1 check passed
@bamdadd
bamdadd deleted the feat/appearance-sidecar branch August 3, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant